#include "MAISObj.h"

MAisDemo::MAisDemo(const TopoDS_Shape& shap, bool indexVisible) :
	myShape(shap),
	faceIndexIsVisible(indexVisible)
{
	myDrawer->SetFaceBoundaryDraw(true);// 要放开头，其余样式设置位置随便
	myDrawer->SetFaceBoundaryAspect(new Prs3d_LineAspect(Quantity_NOC_BLACK , Aspect_TOL_SOLID , 1.0));
}

void MAisDemo::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr , const Handle(Prs3d_Presentation)& thePrs , const Standard_Integer theMode)
{
	if (theMode == MDispMode_WireFrame)
	{
		StdPrs_WFShape::Add(thePrs , myShape , myDrawer);
		setFaceIndex(thePrs);
	}
	else if (theMode == MDispMode_Shaded)
	{
		StdPrs_ShadedShape::Add(thePrs , myShape , myDrawer);
		setFaceIndex(thePrs);
	}
}

void MAisDemo::ComputeSelection(const Handle(SelectMgr_Selection)& theSel , const Standard_Integer theMode)
{
	TopAbs_ShapeEnum TypOfSel = SelectionType(theMode);
	Standard_Real aDefl = StdPrs_ToolTriangulatedShape::GetDeflection(myShape , myDrawer);
	StdSelect_BRepSelectionTool::Load(theSel , this , myShape , TypOfSel , aDefl ,
										   myDrawer->DeviationAngle() ,
										   myDrawer->IsAutoTriangulation());
}

void MAisDemo::SetColor(const Quantity_Color& theColor)
{
	myDrawer->SetupOwnShadingAspect();
	myDrawer->ShadingAspect()->SetColor(theColor);
}

void MAisDemo::setFaceIndex(const Handle(Prs3d_Presentation)& thePrs)
{
	if (faceIndexIsVisible)
	{
		int i = 1;
		for (TopExp_Explorer exp(myShape , TopAbs_FACE); exp.More(); exp.Next() , ++i)
		{
			TopoDS_Face face = TopoDS::Face(exp.Current());

			GProp_GProps props;
			BRepGProp::SurfaceProperties(face , props);
			gp_Pnt center = props.CentreOfMass(); // 获取几何中心

			Handle(Graphic3d_Group) group = thePrs->NewGroup();
			Handle(Graphic3d_AspectText3d) textAspect = new Graphic3d_AspectText3d();
			textAspect->SetColor(Quantity_NOC_BLUE);
			textAspect->SetTextZoomable(false);
			textAspect->SetFont("Consolas");
			textAspect->SetStyle(Aspect_TOST_ANNOTATION);
			group->SetPrimitivesAspect(textAspect);

			Handle(Graphic3d_Text) text = new Graphic3d_Text(20.0);
			text->SetText(std::to_string(i).c_str());
			text->SetPosition(center);
			group->AddText(text);

		}
	}
}

MAisObject::MAisObject(std::shared_ptr< MSLinearRect> shap) :
	myShape(shap)
{
	myShadeStyle = new Prs3d_Drawer();
	myShadeStyle->SetupOwnDefaults();
	myShadeStyle->SetFaceBoundaryDraw(true);// 要放开头，其余样式设置位置随便
	myShadeStyle->SetFaceBoundaryAspect(new Prs3d_LineAspect(Quantity_NOC_BLACK , Aspect_TOL_SOLID , 1.0));
	myShadeStyle->SetWireAspect(new Prs3d_LineAspect(Quantity_NOC_GREEN , Aspect_TOL_SOLID , 1.0));
	// 增加透明度可增加被覆盖内容识别率
	myShadeStyle->ShadingAspect()->SetTransparency(0.5);

	myShadeStyleHighLight = new Prs3d_Drawer();
	myShadeStyleHighLight->SetShadingAspect(new Prs3d_ShadingAspect()); // 新建必须添加aspect，不然后面访问空指针报错
	myShadeStyleHighLight->ShadingAspect()->SetTransparency(0.5);
	myShadeStyleHighLight->SetFaceBoundaryDraw(true);
	myShadeStyleHighLight->SetFaceBoundaryAspect(new Prs3d_LineAspect(Quantity_NOC_GRAY80 , Aspect_TOL_SOLID , 1.0));
}

void MAisObject::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	if (theMode == MDispMode_WireFrame)
	{
		SetDisplayMode(MDispMode_WireFrame);

		StdPrs_WFShape::Add(thePrs , myShape->getShape() , myShadeStyle);
		StdPrs_WFShape::Add(thePrs , myShape->getPath() , myShadeStyle);
		StdPrs_WFShape::Add(thePrs , myShape->getProfile() , myShadeStyle);
	}
	else if (theMode == MDispMode_Shaded)
	{
		SetDisplayMode(MDispMode_Shaded);

		StdPrs_ShadedShape::Add(thePrs , myShape->getShape() , myShadeStyle);
		StdPrs_WFShape::Add(thePrs , myShape->getPath() , myShadeStyle);
		StdPrs_WFShape::Add(thePrs , myShape->getProfile() , myShadeStyle);
	}
	else if (theMode == MDispMode_Shaded_HighLight)
	{
		myShadeStyleHighLight->SetFaceBoundaryAspect(new Prs3d_LineAspect(Quantity_NOC_GRAY80 , Aspect_TOL_SOLID , 1.0));
		StdPrs_ShadedShape::Add(thePrs , myShape->getShape() , myShadeStyleHighLight);

		StdPrs_WFShape::Add(thePrs , myShape->getPath() , myShadeStyle);
		StdPrs_WFShape::Add(thePrs , myShape->getProfile() , myShadeStyle);
	}
	else if (theMode == MDispMode_Shaded_HighLightDynamic)
	{
		myShadeStyleHighLight->SetFaceBoundaryAspect(new Prs3d_LineAspect(Quantity_NOC_CYAN , Aspect_TOL_SOLID , 1.0));
		StdPrs_ShadedShape::Add(thePrs , myShape->getShape() , myShadeStyleHighLight);

		StdPrs_WFShape::Add(thePrs , myShape->getPath() , myShadeStyle);
		StdPrs_WFShape::Add(thePrs , myShape->getProfile() , myShadeStyle);
	}
	else if (theMode == MDispMode_WireFrame_HighLight)
	{
		Handle(Prs3d_Drawer) wireStyle = new Prs3d_Drawer();
		wireStyle->SetupOwnDefaults();
		Handle(Prs3d_LineAspect) lineAspect = new Prs3d_LineAspect(Quantity_NOC_WHITE , Aspect_TOL_SOLID , 1.0);
		wireStyle->SetWireAspect(lineAspect);
		// 默认FreeBoundary绿色
		wireStyle->SetFreeBoundaryAspect(lineAspect);
		// 默认UnFreeBoundary黄色
		wireStyle->SetUnFreeBoundaryAspect(lineAspect);
		StdPrs_WFShape::Add(thePrs , myShape->getPath() , wireStyle);
		StdPrs_WFShape::Add(thePrs , myShape->getShape() , wireStyle);
		StdPrs_WFShape::Add(thePrs , myShape->getProfile() , wireStyle);
	}
}

void MAisObject::ComputeSelection(const Handle(SelectMgr_Selection)& theSel , const Standard_Integer theMode)
{
	TopoDS_Wire path = myShape->getPath();
	TopoDS_Shape aShape = myShape->getShape();
	gp_Pnt endPoint = myShape->getPoints()[0];
	gp_Pnt endPoint1 = myShape->getPoints()[1];
	gp_Pnt aMidPnt = endPoint1.Translated(gp_Vec(endPoint1 , endPoint) * 0.5);

	if (theMode == 0)
	{
		Handle(MAisOwner) aOwner = new MAisOwner(this);
		Standard_Real aDefl = StdPrs_ToolTriangulatedShape::GetDeflection(aShape , myShadeStyle);
		StdSelect_BRepSelectionTool::ComputeSensitive(aShape , aOwner , theSel ,
			aDefl , myShadeStyle->DeviationAngle() , 9 , 500 , myShadeStyle->IsAutoTriangulation());
	}
	else if (theMode == 1)
	{
		Handle(MCaptureOwnerEdge) aCaptureOwnerEdge = new MCaptureOwnerEdge(path , this , 1);
		Handle(Select3D_SensitiveSegment) aSensEdge = new Select3D_SensitiveSegment(aCaptureOwnerEdge , endPoint , endPoint1);
		aSensEdge->SetSensitivityFactor(20);
		theSel->Add(aSensEdge);

		Handle(MCaptureOwnerEndPonit) aCaptureOwnerEndPonit = new MCaptureOwnerEndPonit(endPoint , this , 2);
		Handle(Select3D_SensitivePoint) aSensEndPnt = new Select3D_SensitivePoint(aCaptureOwnerEndPonit , endPoint);
		aSensEndPnt->SetSensitivityFactor(20);
		theSel->Add(aSensEndPnt);

		Handle(MCaptureOwnerEndPonit) aCaptureOwnerEndPonit1 = new MCaptureOwnerEndPonit(endPoint1 , this , 2);
		Handle(Select3D_SensitivePoint) aSensEndPnt1 = new Select3D_SensitivePoint(aCaptureOwnerEndPonit1 , endPoint1);
		aSensEndPnt1->SetSensitivityFactor(20);
		theSel->Add(aSensEndPnt1);

		Handle(MCaptureOwnerMidPoint) aCaptureOwnerMidPoint = new MCaptureOwnerMidPoint(aMidPnt , this , 2);
		Handle(Select3D_SensitivePoint) aSensMidPnt = new Select3D_SensitivePoint(aCaptureOwnerMidPoint , aMidPnt);
		aSensMidPnt->SetSensitivityFactor(20);
		theSel->Add(aSensMidPnt);
	}
}

void MAisObject::SetColor(const Quantity_Color& theColor)
{
	// 自带的myDrawer设置是全局的，所有MAisObject实例都会变
	myShadeStyle->ShadingAspect()->SetColor(theColor);
	// myShadeStyleHighLight设置是实例才会变
	myShadeStyleHighLight->ShadingAspect()->SetColor(theColor);
}

void MAisOwner::HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Drawer)& theStyle ,
	const Standard_Integer theMode)
{
	MAisObject* anObj = dynamic_cast<MAisObject*>(mySelectable);
	std::shared_ptr< MSLinearRect> aShape = anObj->Shape();
	int displayMode = anObj->DisplayMode();
	if (myPrsWire.IsNull())
	{
		myPrsWire = new Prs3d_Presentation(thePrsMgr->StructureManager());
		myPrsWire->SetZLayer(Graphic3d_ZLayerId_Topmost);
		anObj->Compute(thePrsMgr , myPrsWire , MAisObject::MDispMode_WireFrame_HighLight);
	}
	if (myPrs.IsNull())
	{
		myPrs = new Prs3d_Presentation(thePrsMgr->StructureManager());
		myPrs->SetZLayer(Graphic3d_ZLayerId_Topmost);
		anObj->Compute(thePrsMgr , myPrs , MAisObject::MDispMode_Shaded_HighLight);
	}

	if (thePrsMgr->IsImmediateModeOn())
	{
		// 动态高亮指针需与选择高亮指针分开new。如果用同一个，ImmediateList机制会自动erase,导致选择高亮模式也被清除
		// theStyle在Compute中最好也new一个
		if (displayMode == 0)
		{
			Handle(Prs3d_Presentation) myPrsWireD = new Prs3d_Presentation(thePrsMgr->StructureManager());
			anObj->Compute(thePrsMgr , myPrsWireD , MAisObject::MDispMode_WireFrame_HighLight);
			myPrsWireD->Highlight(theStyle);
			thePrsMgr->AddToImmediateList(myPrsWireD);
		}
		else
		{
			Handle(Prs3d_Presentation) myPrsD = new Prs3d_Presentation(thePrsMgr->StructureManager());
			myPrsD->SetZLayer(Graphic3d_ZLayerId_Topmost);
			anObj->Compute(thePrsMgr , myPrsD , MAisObject::MDispMode_Shaded_HighLightDynamic);
			thePrsMgr->AddToImmediateList(myPrsD);
		}
	}
	else
	{
		if (displayMode == 0)
			myPrsWire->Display();
		else
			myPrs->Display();
	}
}

void MAisOwner::Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr , const Standard_Integer theMode)
{
	if (!myPrs.IsNull())
	{
		myPrs->Erase();
	}
	if (!myPrsWire.IsNull())
	{
		myPrsWire->Erase();
	}
}

MCaptureOwnerEndPonit::MCaptureOwnerEndPonit(gp_Pnt& pnt , const Handle(AIS_InteractiveObject)& theObj , int thePriority) :
	SelectMgr_EntityOwner(theObj , thePriority) ,
	myPoint(pnt)
{
	// 不使用HilightWithColor函数参数的全局theStyle，有时中点/端点会错乱。
	myStyle = new Prs3d_Drawer();
	myStyle->SetupOwnDefaults();
	myStyle->PointAspect()->SetScale(Standard_Real(10));
	myStyle->PointAspect()->SetTypeOfMarker(Aspect_TOM_POINT);
	myStyle->PointAspect()->SetColor(Quantity_NOC_YELLOW);
}

void MCaptureOwnerEndPonit::HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Drawer)& theStyle ,
	const Standard_Integer theMode)
{
	if (myPrs.IsNull())
	{
		myPrs = new Prs3d_Presentation(thePrsMgr->StructureManager());

		Handle(Graphic3d_Group) aGroupSegs = myPrs->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myStyle->PointAspect()->Aspect());
		Handle(Graphic3d_ArrayOfPoints) arrPnts = new Graphic3d_ArrayOfPoints(1);
		arrPnts->AddVertex(myPoint);
		aGroupSegs->AddPrimitiveArray(arrPnts);
		myPrs->SetZLayer(Graphic3d_ZLayerId_TopOSD);

	}
	if (myPrsDynamic.IsNull())
	{
		myPrsDynamic = new Prs3d_Presentation(thePrsMgr->StructureManager());
		myPrsDynamic->SetZLayer(Graphic3d_ZLayerId_TopOSD);
		Handle(Graphic3d_Group) aGroupSegs = myPrsDynamic->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myStyle->PointAspect()->Aspect());
		Handle(Graphic3d_ArrayOfPoints) arrPnts = new Graphic3d_ArrayOfPoints(1);
		arrPnts->AddVertex(myPoint);
		aGroupSegs->AddPrimitiveArray(arrPnts);

		myPrsDynamic->Highlight(myStyle); // 和下面有先后顺序
		myPrsDynamic->HighlightStyle()->SetColor(Quantity_NOC_CYAN);
	}
	if (thePrsMgr->IsImmediateModeOn())
	{
		thePrsMgr->AddToImmediateList(myPrsDynamic);
	}
	else
	{
		myPrs->Display();
	}
}

void MCaptureOwnerEndPonit::Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr , const Standard_Integer theMode)
{
	if (!myPrs.IsNull())
	{
		myPrs->Erase();
	}
	if (!myPrsDynamic.IsNull())
	{
		myPrsDynamic->Erase();
	}
}

MCaptureOwnerMidPoint::MCaptureOwnerMidPoint(gp_Pnt& pnt , const Handle(AIS_InteractiveObject)& theObj , int thePriority) :
	SelectMgr_EntityOwner(theObj , thePriority) ,
	myPoint(pnt)
{
	const char* path = "E:/8other/CppLearn/OCCTTutorial/OCCTQtDemo/icons/triangle.png";
	Handle(Image_AlienPixMap) pix = new Image_AlienPixMap();
	pix->Load(path);
	img = new Graphic3d_MarkerImage(pix);

	myStyle = new Prs3d_Drawer();
	myStyle->SetupOwnDefaults();
	myStyle->PointAspect()->SetTypeOfMarker(Aspect_TOM_USERDEFINED);
	myStyle->PointAspect()->Aspect()->SetMarkerImage(img);
}

void MCaptureOwnerMidPoint::HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr , const Handle(Prs3d_Drawer)& theStyle , const Standard_Integer theMode)
{
	if (myPrs.IsNull())
	{
		myPrs = new Prs3d_Presentation(thePrsMgr->StructureManager());

		Handle(Graphic3d_Group) aGroupSegs = myPrs->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myStyle->PointAspect()->Aspect());
		Handle(Graphic3d_ArrayOfPoints) arrPnts = new Graphic3d_ArrayOfPoints(1);
		arrPnts->AddVertex(myPoint);
		aGroupSegs->AddPrimitiveArray(arrPnts);
		myPrs->SetZLayer(Graphic3d_ZLayerId_TopOSD);
	}
	if (myPrsDynamic.IsNull())
	{
		myPrsDynamic = new Prs3d_Presentation(thePrsMgr->StructureManager());

		Handle(Graphic3d_Group) aGroupSegs = myPrsDynamic->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myStyle->PointAspect()->Aspect());
		Handle(Graphic3d_ArrayOfPoints) arrPnts = new Graphic3d_ArrayOfPoints(1);
		arrPnts->AddVertex(myPoint);
		aGroupSegs->AddPrimitiveArray(arrPnts);
		myPrsDynamic->SetZLayer(Graphic3d_ZLayerId_TopOSD);

		myPrsDynamic->Highlight(myStyle); // 和下面有先后顺序
		myPrsDynamic->HighlightStyle()->SetColor(Quantity_NOC_CYAN);
	}
	if (thePrsMgr->IsImmediateModeOn())
	{
		thePrsMgr->AddToImmediateList(myPrsDynamic);
	}
	else
	{
		myPrs->Display();
	}
}

void MCaptureOwnerMidPoint::Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr , const Standard_Integer theMode)
{
	if (!myPrs.IsNull())
	{
		myPrs->Erase();
	}
	if (!myPrsDynamic.IsNull())
	{
		myPrsDynamic->Erase();
	}
}

MCaptureOwnerEdge::MCaptureOwnerEdge(TopoDS_Wire& edge , const Handle(AIS_InteractiveObject)& theObj , int thePriority) :
	SelectMgr_EntityOwner(theObj , thePriority) ,
	myEdge(edge)
{
	myStyle = new Prs3d_Drawer();
	myStyle->SetupOwnDefaults();
	myStyle->WireAspect()->SetColor(Quantity_NOC_YELLOW);
}

void MCaptureOwnerEdge::HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Drawer)& theStyle , const Standard_Integer theMode)
{
	if (myPrs.IsNull())
	{
		myPrs = new Prs3d_Presentation(thePrsMgr->StructureManager());
		myPrs->SetZLayer(Graphic3d_ZLayerId_TopOSD);

		StdPrs_ShadedShape::Add(myPrs , myEdge , myStyle);
	}

	if (thePrsMgr->IsImmediateModeOn())
	{
		Handle(Prs3d_Presentation) myPrsD = new Prs3d_Presentation(thePrsMgr->StructureManager());
		myPrsD->SetZLayer(Graphic3d_ZLayerId_TopOSD);

		StdPrs_ShadedShape::Add(myPrsD , myEdge , myStyle);
		myPrsD->Highlight(myStyle); // 和下面有先后顺序
		myPrsD->HighlightStyle()->SetColor(Quantity_NOC_CYAN);
		thePrsMgr->AddToImmediateList(myPrsD);
	}
	else
	{
		myPrs->Display();
	}
}

void MCaptureOwnerEdge::Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr , const Standard_Integer theMode)
{
	if (!myPrs.IsNull())
	{
		myPrs->Erase();
	}
}

MAisObject0::MAisObject0(const TopoDS_Shape& shap) :
	aShape(shap)
{
	SetDisplayMode(MyDispMode_Main);
	SetHilightMode(MyDispMode_Highlight);
}

void MAisObject0::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	if (theMode == MyDispMode_Main)
	{
		StdPrs_ShadedShape::Add(thePrs , aShape , myDrawer);
		StdPrs_WFShape::Add(thePrs , aShape , myDrawer);
	}
	else if (theMode == MyDispMode_Highlight)
	{
		Bnd_Box aBox;
		BRepBndLib::Add(aShape , aBox);
		Prs3d_BndBox::Add(thePrs , aBox , myDrawer);
	}
}

MAisObject1::MAisObject1(const TopoDS_Shape& shap) :
	aShape(shap)
{
	SetDisplayMode(MyDispMode_Main);
	SetHilightMode(MyDispMode_Highlight);
}

void MAisObject1::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	const double aRadius = 100.0 , aHeight = 100.0;
	if (theMode == MyDispMode_Main)
	{
		StdPrs_ShadedShape::Add(thePrs , aShape , myDrawer);
		//StdPrs_WFShape::Add (thePrs, aShape, myDrawer);
		const double aRadius = 100.0 , aHeight = 100.0;
		Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments(4 , 4 * 2 , Graphic3d_ArrayFlags_None);
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , 0.0));
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , 0.0));
		aSegs->AddEdges(1 , 2);
		aSegs->AddEdges(2 , 3);
		aSegs->AddEdges(3 , 4);
		aSegs->AddEdges(4 , 1);
		Handle(Graphic3d_Group) aGroupSegs = thePrs->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myDrawer->WireAspect()->Aspect());
		aGroupSegs->AddPrimitiveArray(aSegs);
	}
	else if (theMode == MyDispMode_Highlight)
	{
		Bnd_Box aBox;
		BRepBndLib::Add(aShape , aBox);
		Prs3d_BndBox::Add(thePrs , aBox , myDrawer);
	}
}

MAisObject2::MAisObject2(const TopoDS_Shape& shap) :
	aShape(shap)
{
	SetHilightMode(MyDispMode_Highlight);
	myDrawer->SetupOwnShadingAspect();
	myDrawer->ShadingAspect()->SetMaterial(Graphic3d_NameOfMaterial_Silver);
	myDrawer->SetWireAspect(new Prs3d_LineAspect(Quantity_NOC_GREEN , Aspect_TOL_SOLID , 2.0));
}

void MAisObject2::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	if (theMode == MyDispMode_Main)
	{
		StdPrs_ShadedShape::Add(thePrs , aShape , myDrawer);
		//StdPrs_WFShape::Add (thePrs, aShape, myDrawer);
		const double aRadius = 100.0 , aHeight = 100.0;
		Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments(4 , 4 * 2 , Graphic3d_ArrayFlags_None);
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , 0.0));
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , 0.0));
		aSegs->AddEdges(1 , 2);
		aSegs->AddEdges(2 , 3);
		aSegs->AddEdges(3 , 4);
		aSegs->AddEdges(4 , 1);
		Handle(Graphic3d_Group) aGroupSegs = thePrs->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myDrawer->WireAspect()->Aspect());
		aGroupSegs->AddPrimitiveArray(aSegs);
	}
	else if (theMode == MyDispMode_Highlight)
	{
		Bnd_Box aBox;
		BRepBndLib::Add(aShape , aBox);
		Prs3d_BndBox::Add(thePrs , aBox , myDrawer);
	}
}

MAisObject3::MAisObject3(const TopoDS_Shape& shap) :
	aShape(shap)
{
	SetHilightMode(MyDispMode_Highlight);
	myDrawer->SetupOwnShadingAspect();
	myDrawer->ShadingAspect()->SetMaterial(Graphic3d_NameOfMaterial_Silver);
	myDrawer->SetWireAspect(new Prs3d_LineAspect(Quantity_NOC_GREEN , Aspect_TOL_SOLID , 2.0));
}

void MAisObject3::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	const double aRadius = 100.0 , aHeight = 100.0;
	if (theMode == MyDispMode_Main)
	{
		Prs3d_ToolCylinder aCyl(aRadius , aRadius , aHeight , 25 , 25);
		Prs3d_ToolDisk aDisk(0.0 , aRadius , 25 , 1);
		Handle(Graphic3d_ArrayOfTriangles) aTris =
			new Graphic3d_ArrayOfTriangles(aCyl.VerticesNb() + 2 * aDisk.VerticesNb() ,
											3 * (aCyl.TrianglesNb() + 2 * aDisk.TrianglesNb()) ,
											Graphic3d_ArrayFlags_VertexNormal);
		aCyl.FillArray(aTris , gp_Trsf());
		aDisk.FillArray(aTris , gp_Trsf());

		gp_Trsf aDisk2Trsf;
		aDisk2Trsf.SetTransformation(gp_Ax3(gp_Pnt(0.0 , 0.0 , aHeight) , -gp::DZ() , gp::DX()) , gp::XOY());
		aDisk.FillArray(aTris , aDisk2Trsf);

		Handle(Graphic3d_Group) aGroupTris = thePrs->NewGroup();
		aGroupTris->SetGroupPrimitivesAspect(myDrawer->ShadingAspect()->Aspect());
		aGroupTris->AddPrimitiveArray(aTris);
		aGroupTris->SetClosed(true);

		Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments(4 , 4 * 2 , Graphic3d_CappingFlags_None);
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , 0.0));
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , 0.0));
		aSegs->AddEdges(1 , 2);
		aSegs->AddEdges(2 , 3);
		aSegs->AddEdges(3 , 4);
		aSegs->AddEdges(4 , 1);
		Handle(Graphic3d_Group) aGroupSegs = thePrs->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myDrawer->WireAspect()->Aspect());
		aGroupSegs->AddPrimitiveArray(aSegs);
	}
	else if (theMode == MyDispMode_Highlight)
	{
		Bnd_Box aBox;
		BRepBndLib::Add(aShape , aBox);
		Prs3d_BndBox::Add(thePrs , aBox , myDrawer);
	}
}

MAisObject4::MAisObject4(const TopoDS_Shape& shap) :
	aShape(shap)
{
	SetDisplayMode(MyDispMode_Main);
	SetHilightMode(MyDispMode_Highlight);
}

void MAisObject4::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	const double aRadius = 100.0 , aHeight = 100.0;
	if (theMode == MyDispMode_Main)
	{
		Prs3d_ToolCylinder aCyl(aRadius , aRadius , aHeight , 25 , 25);
		Prs3d_ToolDisk aDisk(0.0 , aRadius , 25 , 1);
		Handle(Graphic3d_ArrayOfTriangles) aTris =
			new Graphic3d_ArrayOfTriangles(aCyl.VerticesNb() + 2 * aDisk.VerticesNb() ,
											3 * (aCyl.TrianglesNb() + 2 * aDisk.TrianglesNb()) ,
											Graphic3d_ArrayFlags_VertexNormal);
		aCyl.FillArray(aTris , gp_Trsf());
		aDisk.FillArray(aTris , gp_Trsf());

		gp_Trsf aDisk2Trsf;
		aDisk2Trsf.SetTransformation(gp_Ax3(gp_Pnt(0.0 , 0.0 , aHeight) , -gp::DZ() , gp::DX()) , gp::XOY());
		aDisk.FillArray(aTris , aDisk2Trsf);

		Handle(Graphic3d_Group) aGroupTris = thePrs->NewGroup();
		aGroupTris->SetGroupPrimitivesAspect(myDrawer->ShadingAspect()->Aspect());
		aGroupTris->AddPrimitiveArray(aTris);
		aGroupTris->SetClosed(true);

		Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments(4 , 4 * 2 , Graphic3d_CappingFlags_None);
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , 0.0));
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , 0.0));
		aSegs->AddEdges(1 , 2);
		aSegs->AddEdges(2 , 3);
		aSegs->AddEdges(3 , 4);
		aSegs->AddEdges(4 , 1);
		Handle(Graphic3d_Group) aGroupSegs = thePrs->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myDrawer->WireAspect()->Aspect());
		aGroupSegs->AddPrimitiveArray(aSegs);
	}
	else if (theMode == MyDispMode_Highlight)
	{
		Bnd_Box aBox;
		BRepBndLib::Add(aShape , aBox);
		Prs3d_BndBox::Add(thePrs , aBox , myDrawer);
	}
}

void MAisObject4::ComputeSelection(const Handle(SelectMgr_Selection)& theSel , const Standard_Integer theMode)
{
	if (theMode != 0) {
		return;
	}
	Bnd_Box aBox;
	BRepBndLib::Add(aShape , aBox);
	Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this);
	Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox(anOwner , aBox);
	theSel->Add(aSensBox);

	//Standard_Real aDefl = StdPrs_ToolTriangulatedShape::GetDeflection (aShape,myDrawer);
	//StdSelect_BRepSelectionTool::Load (theSel,this,aShape,TopAbs_SHAPE,aDefl,
	//								   myDrawer->DeviationAngle(),
	//								   myDrawer->IsAutoTriangulation());

	//const double aRadius = 100.0 , aHeight = 100.0;
	//Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this);
	//Handle(Graphic3d_ArrayOfTriangles) aTris =
	//	Prs3d_ToolCylinder::Create(aRadius , aRadius , aHeight , 25 , 25 , gp_Trsf());
	//Handle(Select3D_SensitivePrimitiveArray) aSensTri =
	//	new Select3D_SensitivePrimitiveArray(anOwner);
	//aSensTri->InitTriangulation(aTris->Attributes() , aTris->Indices() ,
	//							 TopLoc_Location());
	//theSel->Add(aSensTri);
}

MAisObject5::MAisObject5(const TopoDS_Shape& shap) :
	aShape(shap)
{
	myDrawer->SetupOwnShadingAspect();
	myDrawer->ShadingAspect()->SetMaterial(Graphic3d_NameOfMaterial_Silver);
	myDrawer->SetWireAspect(new Prs3d_LineAspect(Quantity_NOC_GREEN , Aspect_TOL_SOLID , 2.0));
}

void MAisObject5::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	const double aRadius = 100.0 , aHeight = 100.0;
	if (theMode == MyDispMode_Main)
	{
		Prs3d_ToolCylinder aCyl(aRadius , aRadius , aHeight , 25 , 25);
		Prs3d_ToolDisk aDisk(0.0 , aRadius , 25 , 1);
		Handle(Graphic3d_ArrayOfTriangles) aTris =
			new Graphic3d_ArrayOfTriangles(aCyl.VerticesNb() + 2 * aDisk.VerticesNb() ,
											3 * (aCyl.TrianglesNb() + 2 * aDisk.TrianglesNb()) ,
											Graphic3d_ArrayFlags_VertexNormal);
		aCyl.FillArray(aTris , gp_Trsf());
		aDisk.FillArray(aTris , gp_Trsf());

		gp_Trsf aDisk2Trsf;
		aDisk2Trsf.SetTransformation(gp_Ax3(gp_Pnt(0.0 , 0.0 , aHeight) , -gp::DZ() , gp::DX()) , gp::XOY());
		aDisk.FillArray(aTris , aDisk2Trsf);

		Handle(Graphic3d_Group) aGroupTris = thePrs->NewGroup();
		aGroupTris->SetGroupPrimitivesAspect(myDrawer->ShadingAspect()->Aspect());
		aGroupTris->AddPrimitiveArray(aTris);
		aGroupTris->SetClosed(true);

		Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments(4 , 4 * 2 , Graphic3d_CappingFlags_None);
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , 0.0));
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , 0.0));
		aSegs->AddEdges(1 , 2);
		aSegs->AddEdges(2 , 3);
		aSegs->AddEdges(3 , 4);
		aSegs->AddEdges(4 , 1);
		Handle(Graphic3d_Group) aGroupSegs = thePrs->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myDrawer->WireAspect()->Aspect());
		aGroupSegs->AddPrimitiveArray(aSegs);
	}
	else if (theMode == MyDispMode_Highlight)
	{
		Bnd_Box aBox;
		BRepBndLib::Add(aShape , aBox);
		Prs3d_BndBox::Add(thePrs , aBox , myDrawer);
	}
}

void MAisObject5::ComputeSelection(const Handle(SelectMgr_Selection)& theSel , const Standard_Integer theMode)
{
	if (theMode != 0) {
		return;
	}
	const double aRadius = 100.0 , aHeight = 100.0;
	Handle(MAisOwner5) anOwner = new MAisOwner5(this);
	Handle(Graphic3d_ArrayOfTriangles) aTris =
		Prs3d_ToolCylinder::Create(aRadius , aRadius , aHeight , 25 , 25 , gp_Trsf());
	Handle(Select3D_SensitivePrimitiveArray) aSensTri =
		new Select3D_SensitivePrimitiveArray(anOwner);
	aSensTri->InitTriangulation(aTris->Attributes() , aTris->Indices() ,
								 TopLoc_Location());
	theSel->Add(aSensTri);
}

MAisObject6::MAisObject6(const TopoDS_Shape& shap) :
	aShape(shap)
{
	myDrawer->SetupOwnShadingAspect();
	myDrawer->ShadingAspect()->SetMaterial(Graphic3d_NameOfMaterial_Silver);
	myDrawer->SetWireAspect(new Prs3d_LineAspect(Quantity_NOC_GREEN , Aspect_TOL_SOLID , 2.0));
}

void MAisObject6::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	const double aRadius = 100.0 , aHeight = 100.0;
	if (theMode == MyDispMode_Main)
	{
		Prs3d_ToolCylinder aCyl(aRadius , aRadius , aHeight , 25 , 25);
		Prs3d_ToolDisk aDisk(0.0 , aRadius , 25 , 1);
		Handle(Graphic3d_ArrayOfTriangles) aTris =
			new Graphic3d_ArrayOfTriangles(aCyl.VerticesNb() + 2 * aDisk.VerticesNb() ,
											3 * (aCyl.TrianglesNb() + 2 * aDisk.TrianglesNb()) ,
											Graphic3d_ArrayFlags_VertexNormal);
		aCyl.FillArray(aTris , gp_Trsf());
		aDisk.FillArray(aTris , gp_Trsf());

		gp_Trsf aDisk2Trsf;
		aDisk2Trsf.SetTransformation(gp_Ax3(gp_Pnt(0.0 , 0.0 , aHeight) , -gp::DZ() , gp::DX()) , gp::XOY());
		aDisk.FillArray(aTris , aDisk2Trsf);

		Handle(Graphic3d_Group) aGroupTris = thePrs->NewGroup();
		aGroupTris->SetGroupPrimitivesAspect(myDrawer->ShadingAspect()->Aspect());
		aGroupTris->AddPrimitiveArray(aTris);
		aGroupTris->SetClosed(true);

		Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments(4 , 4 * 2 , Graphic3d_CappingFlags_None);
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , 0.0));
		aSegs->AddVertex(gp_Pnt(0.0 , -aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , aHeight));
		aSegs->AddVertex(gp_Pnt(0.0 , aRadius , 0.0));
		aSegs->AddEdges(1 , 2);
		aSegs->AddEdges(2 , 3);
		aSegs->AddEdges(3 , 4);
		aSegs->AddEdges(4 , 1);
		Handle(Graphic3d_Group) aGroupSegs = thePrs->NewGroup();
		aGroupSegs->SetGroupPrimitivesAspect(myDrawer->WireAspect()->Aspect());
		aGroupSegs->AddPrimitiveArray(aSegs);
	}
	else if (theMode == MyDispMode_Highlight)
	{
		Bnd_Box aBox;
		BRepBndLib::Add(aShape , aBox);
		Prs3d_BndBox::Add(thePrs , aBox , myDrawer);
	}
}

void MAisObject6::ComputeSelection(const Handle(SelectMgr_Selection)& theSel , const Standard_Integer theMode)
{
	if (theMode != 0) {
		return;
	}
	const double aRadius = 100.0 , aHeight = 100.0;
	Handle(MAisOwner6) anOwner = new MAisOwner6(this);
	Handle(Graphic3d_ArrayOfTriangles) aTris =
		Prs3d_ToolCylinder::Create(aRadius , aRadius , aHeight , 25 , 25 , gp_Trsf());
	Handle(Select3D_SensitivePrimitiveArray) aSensTri =
		new Select3D_SensitivePrimitiveArray(anOwner);
	aSensTri->InitTriangulation(aTris->Attributes() , aTris->Indices() ,
								 TopLoc_Location());
	theSel->Add(aSensTri);
}

myPk_IShape::myPk_IShape(const TopoDS_Shape& theShape , PrsMgr_TypeOfPresentation3d theType) :
	AIS_InteractiveObject(theType) ,
	myShape(theShape)
{
	SetHilightMode(0);
}

void myPk_IShape::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						   const Handle(Prs3d_Presentation)& thePrs ,
						   const Standard_Integer theMode)
{
	switch (theMode)
	{
		// algo for calculation of wireframe presentation
	case 0: StdPrs_WFShape::Add(thePrs , myShape , myDrawer); return;
		// algo for calculation of shading presentation
	case 1: StdPrs_ShadedShape::Add(thePrs , myShape , myDrawer); return;
	}
}

void myPk_IShape::computeHLR(const Handle(Graphic3d_Camera)& theProjector ,
		const Handle(TopLoc_Datum3D)& theTrsf ,
		const Handle(Prs3d_Presentation)& thePrs)
{
	// Hidden line mode calculation algorithm
	StdPrs_HLRPolyShape hlr;
	hlr.ComputeHLR(thePrs , myShape , myDrawer , theProjector);
}

void myPk_IShape::SetColor(const Quantity_Color& theColor)
{
	myDrawer->ShadingAspect()->SetColor(theColor);
}

MAisObject7::MAisObject7()
{
}

void MAisObject7::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	if (theMode == MDispMode_WireFrame)
	{
		Handle(Graphic3d_ArrayOfTriangles) anArray = new Graphic3d_ArrayOfTriangles(4 , 6 , Graphic3d_ArrayFlags_None);
		anArray->AddVertex(-1.0 , 0.0 , 0.0); // vertex 1
		anArray->AddVertex(1.0 , 0.0 , 0.0); // vertex 2
		anArray->AddVertex(0.0 , 1.0 , 0.0); // vertex 3
		anArray->AddVertex(0.0 , -1.0 , 0.0); // vertex 4
		// add edges to the array
		anArray->AddEdges(1 , 2 , 3); // first triangle
		anArray->AddEdges(1 , 2 , 4); // second triangle
		// add the array to the structure
		Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
		aGroup->AddPrimitiveArray(anArray);
		aGroup->SetGroupPrimitivesAspect(myDrawer->ShadingAspect()->Aspect());
	}
}

void MAisObject7::ComputeSelection(const Handle(SelectMgr_Selection)& theSel , const Standard_Integer theMode)
{
}

void MAisObject8::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs , const Standard_Integer theMode)
{
	Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
	// change the text aspect
	Handle(Graphic3d_AspectText3d) aTextAspect = new Graphic3d_AspectText3d();
	aTextAspect->SetTextZoomable(true);
	//aTextAspect->SetTextAngle(45.0);
	aTextAspect->SetFont("Consolas");
	aGroup->SetPrimitivesAspect(aTextAspect);

	// add a text primitive to the structure
	Handle(Graphic3d_Text) aText = new Graphic3d_Text(16.0f);
	aText->SetText("Text你好啊");
	aText->SetPosition(gp_Pnt(1 , 1 , 1));
	aGroup->AddText(aText);
}

MAisObject9::MAisObject9(TopoDS_Shape& shap) :
	myShape(shap)
{
	myDrawer->SetFaceBoundaryDraw(true);// 要放开头，其余样式设置位置随便
	myDrawer->SetFaceBoundaryAspect(new Prs3d_LineAspect(Quantity_NOC_BLACK , Aspect_TOL_SOLID , 1.0));
}

void MAisObject9::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Presentation)& thePrs ,
	const Standard_Integer theMode)
{
	if (theMode == MDispMode_WireFrame)
	{
		StdPrs_ShadedShape::Add(thePrs , myShape , myDrawer);

		Bnd_Box aBox;
		BRepBndLib::Add(myShape , aBox);
		Prs3d_BndBox::Add(thePrs , aBox , myDrawer);
	}
	else if (theMode == MDispMode_Shaded)
	{
		StdPrs_ShadedShape::Add(thePrs , myShape , myDrawer);

		Bnd_OBB aBox;
		BRepBndLib::AddOBB(myShape , aBox);
		Prs3d_BndBox::Add(thePrs , aBox , myDrawer);
	}
}

void MAisObject9::ComputeSelection(const Handle(SelectMgr_Selection)& theSel , const Standard_Integer theMode)
{
	Bnd_Box aBox;
	BRepBndLib::Add(myShape , aBox);

	Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this);
	Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox(anOwner , aBox);
	theSel->Add(aSensBox);
}

void MAisOwner5::HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Drawer)& theStyle ,
	const Standard_Integer theMode)
{
	if (myPrs.IsNull())
	{
		myPrs = new Prs3d_Presentation(thePrsMgr->StructureManager());
		MAisObject5* anObj = dynamic_cast<MAisObject5*> (mySelectable);
		anObj->Compute(thePrsMgr , myPrs , MAisObject5::MyDispMode_Highlight);
	}
	if (thePrsMgr->IsImmediateModeOn())
	{
		// 使用此方法获取的aShadow不能高亮显示Box
		Handle(Prs3d_PresentationShadow) aShadow =
			new Prs3d_PresentationShadow(thePrsMgr->StructureManager() , myPrs);
		// 自动设置myPrs的高亮颜色
		aShadow->SetZLayer(Graphic3d_ZLayerId_Top);
		aShadow->Highlight(theStyle);

		thePrsMgr->AddToImmediateList(aShadow);
	}
	else
	{
		myPrs->Display();
	}
}

void MAisOwner5::Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr , const Standard_Integer theMode)
{
	if (!myPrs.IsNull()) {
		myPrs->Erase();
	}
}

void MAisOwner6::HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
	const Handle(Prs3d_Drawer)& theStyle ,
	const Standard_Integer theMode)
{
	MAisObject6* anObj = dynamic_cast<MAisObject6*>(mySelectable);
	if (thePrsMgr->IsImmediateModeOn())
	{
		// 文档有误， 类型为StdSelect_ViewerSelector3d
		Handle(StdSelect_ViewerSelector3d) aSelector = anObj->InteractiveContext()->MainSelector();
		SelectMgr_SortCriterion aPickPnt;
		for (int aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
		{
			if (aSelector->Picked(aPickIter) == this)
			{
				aPickPnt = aSelector->PickedData(aPickIter);
				break;
			}
		}

		Handle(Prs3d_Presentation) aPrs = mySelectable->GetHilightPresentation(thePrsMgr);
		aPrs->SetZLayer(Graphic3d_ZLayerId_Top);
		aPrs->Clear();
		// 文档有误，变量名为aGroupPnt
		Handle(Graphic3d_Group) aGroupPnt = aPrs->NewGroup();
		aGroupPnt->SetGroupPrimitivesAspect(theStyle->ArrowAspect()->Aspect());
		gp_Trsf aTrsfInv = mySelectable->LocalTransformation().Inverted();
		gp_Dir  aNorm(aPickPnt.Normal.x() , aPickPnt.Normal.y() , aPickPnt.Normal.z());
		Handle(Graphic3d_ArrayOfTriangles) aTris = Prs3d_Arrow::DrawShaded(
			gp_Ax1(aPickPnt.Point , aNorm).Transformed(aTrsfInv) ,
			  1.0 , 15.0 ,
			  3.0 , 4.0 , 10);
		aGroupPnt->AddPrimitiveArray(aTris);
		thePrsMgr->AddToImmediateList(aPrs);
	}
}

void MAisOwner6::Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr , const Standard_Integer theMode)
{
	if (!myPrs.IsNull()) {
		myPrs->Erase();
	}
}